/*
 * Copyright 2007-2010 VTT Biotechnology
 * This file is part of GopiBugs.
 *
 * GopiBugs is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * GopiBugs is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * GopiBugs; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
 * Fifth Floor, Boston, MA 02110-1301 USA
 */
package PD.modules.simulation.control;

import PD.data.NetworkDataset;
import PD.data.Row;
import PD.data.impl.SimpleParameterSet;
import PD.main.PDCore;
import PD.modules.simulation.Bug;
import PD.modules.simulation.Result;
import PD.modules.simulation.World;
import PD.taskcontrol.TaskStatus;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

/**
 *
 * @author scsandra
 */
public class StartSimulationTask {

        private NetworkDataset networkDS;
        private TaskStatus status = TaskStatus.WAITING;
        private String errorMessage;
        private sinkThread thread;
        private World world;
        private int maxNumberOfBugs, numberOfChromosomes, mutationRate, stoppingCriteria;
        private JTextArea textArea;
        private List<Result> results;
        private Bug bestBug;
        private int counter = 0;

        public StartSimulationTask(NetworkDataset[] datasets, SimpleParameterSet parameters) {

                networkDS = datasets[0];

                this.maxNumberOfBugs = (Integer) parameters.getParameterValue(StartSimulationParameters.numberOfBugs);

                this.numberOfChromosomes = (Integer) parameters.getParameterValue(StartSimulationParameters.numberOfChromosomes);

                this.mutationRate = (Integer) parameters.getParameterValue(StartSimulationParameters.mutationRate);

                this.stoppingCriteria = (Integer) parameters.getParameterValue(StartSimulationParameters.numberOfcycles);

                this.results = new ArrayList<Result>();

        }

        public String getTaskDescription() {
                return "Start simulation... ";
        }

        public double getFinishedPercentage() {
                return 0.0f;
        }

        public TaskStatus getStatus() {
                return status;
        }

        public String getErrorMessage() {
                return errorMessage;
        }

        public void cancel() {
                status = TaskStatus.CANCELED;
        }

        public void run() {
                try {
                        status = TaskStatus.PROCESSING;
                        JInternalFrame frame2 = new JInternalFrame("Results", true, true, true, true);
                        frame2.setSize(new Dimension(700, 700));

                        textArea = new JTextArea("");
                        textArea.setSize(new Dimension(700, 700));
                        JScrollPane panel = new JScrollPane(textArea);
                        frame2.add(panel);
                        PDCore.getDesktop().addInternalFrame(frame2);

                        world = new World(networkDS, this.numberOfChromosomes, this.maxNumberOfBugs, this.mutationRate, this.stoppingCriteria);
                        thread = new sinkThread();
                        thread.start();
                        status = TaskStatus.FINISHED;
                } catch (Exception e) {
                        e.printStackTrace();
                        status = TaskStatus.ERROR;
                }
        }

        public class sinkThread extends Thread {

                @Override
                public void run() {
                        while (1 == 1) {
                                world.cicle();
                                List<Bug> bugs = world.getPopulation();
                                try {
                                        if (bugs.size() > 0 && (bestBug == null || bugs.get(0).getWeight() > bestBug.getWeight())) {
                                                bestBug = bugs.get(0);
                                                counter = 0;
                                        }

                                        counter++;
                                        System.out.println("counter: " + counter);
                                } catch (NullPointerException e) {
                                }

                                printResult(bugs, false);
                                if (counter == stoppingCriteria) {
                                        // bestBug.completeNetwork();
                                        // printResult(bugs, true);
                                        break;
                                }

                        }
                }
        }

        public void printResult(List<Bug> bugs, boolean complete) {
                if (bugs.size() > 0) {
                        this.results.clear();
                        int numberPrint = 25;
                        if (numberPrint > bugs.size()) {
                                numberPrint = bugs.size();
                        }

                        for (int i = 0; i < numberPrint; i++) {
                                Bug bug = bugs.get(i);
                                Result result = new Result(bug);
                                this.results.add(result);

                        }
                        String result = "Counter: " + this.counter + "\n";
                        if (complete) {
                                result = this.textArea.getText() + "\n";
                        }

                        for (int i = 0; i < numberPrint; i++) {
                                result += results.get(i).toString();
                        }

                        // Print the combined result

                        String text = "\ngraph [\n\tcomment \"result\"";
                        for (int i = 0; i < 5; i++) {
                                Bug bug = bugs.get(i);
                                for (Row node : bug.getFinalDataset().getNodesRows()) {
                                        text += node.toString();
                                }
                        }

                        for (int i = 0; i < 5; i++) {
                                Bug bug = bugs.get(i);
                                for (Row edge : bug.getFinalDataset().getEdgesRows()) {
                                        text += edge.toString();
                                }
                        }
                        text += "\n]";
                        result += text;

                        // System.out.println(result);
                        this.textArea.setText(result);
                }

        }
}
